home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4_src.zip / TNL7U.C < prev    next >
Text File  |  1995-02-12  |  30KB  |  841 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7, Utilities                                 */
  22. /* Version 1.01                                     */
  23. /* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig         */
  24. /* 14-MAY-88                                     */
  25.  
  26. /* G8KBB April 1991 - add register keyword to compress code
  27.  *                  - use all.h header file
  28.  *                  - use putnum_and_space optionally on MODIFIED
  29.  *                  - make putnbr() optionally show alias:callsign
  30.  *
  31.  * September 1993 - released as TheNet X-1J
  32.  *
  33.  * Add optional support for TexNet on declaration of TEXNET
  34.  */
  35.  
  36. #include "all.h"
  37. #include "tntyp.h"        /* Definition der Typen                 */
  38. #include "tnl7ue.h"        /* externe Definitionen                 */
  39.  
  40. /*---------------------------------------------------------------------------*/
  41. VOID    kilusr()        /* User abwerfen                 */
  42.   {
  43.   register mhtyp *bufpoi;    /* MBHD fuer Meldungen                 */
  44.  
  45.   if ((bufpoi = userpo->mbhd) != 0) /* noch Info im Buffer?             */
  46.     dealmb(bufpoi);        /* dann vernichten                 */
  47.  
  48.   dealoc(unlink(userpo));    /* User Kontrollblock auch wieder frei         */
  49.   userpo = 0;            /* Userpointer ungueltig machen             */
  50.   }
  51.  
  52. /*---------------------------------------------------------------------------*/
  53. VOID    invcal()        /* ungueltiges Rufzeichen melden         */
  54.   {
  55.   putmsg("Invalid Call");
  56.   }
  57.  
  58. /*---------------------------------------------------------------------------*/
  59. VOID    makcon(usrp)        /* Verbindung melden, Eintrag herstellen     */
  60. register usrtyp *usrp;                /* Userkontrollblock             */
  61.   {
  62.   msgfrm('U', (ptcrdp->luserl = usrp->cblk_u),
  63.               (ptcrdp->lusert = usrp->typ_u), conmsg);
  64.   }
  65.  
  66. /*---------------------------------------------------------------------------*/
  67. VOID    msgfrm(seite, link, user, msg) /* Systemstatus melden             */
  68. unsigned seite;            /* Uplink - Downlink                 */
  69. register unsigned user;        /* Usertyp: 0=Host, 2=Level2, 4=Circuit         */
  70. register ctyp *link;        /* Kontrollblock des Users             */
  71. char     *msg;            /* Meldung                     */
  72.   {
  73.   register mhtyp *bufpoi;            /* MBHD der Meldung         */
  74.  
  75.   bufpoi = putals(msg);                /* Meldung ausgeben         */
  76.   if (seite == 'D')                /* Downlink?             */
  77.    {
  78.     if (user == 4)                /* User ist Circuit?         */
  79.       putalt(link->l3blk.l3node->nodide, bufpoi);    /* dann Ident vorweg         */
  80.     else                    /* Level2 oder Host?         */
  81.      if (user == 0)
  82.        putalt(alias, bufpoi);            /* bei Host auch Ident         */
  83.    }
  84.   putid(calofs(seite, link, user), bufpoi);    /* Call immer ausgeben         */
  85.   seteom(bufpoi);                /* Ende Kennung dazu         */
  86.   }
  87.  
  88. /*---------------------------------------------------------------------------*/
  89. VOID    puttfu(name)        /* Tabelle voll melden                 */
  90. char    *name;            /* Tabellenname                     */
  91.   {
  92.   register mhtyp *bufpoi;    /* MBHD der Meldung                 */
  93.  
  94.   putstr(" table full", (bufpoi = putals(name))); /* Meldung             */
  95.   seteom(bufpoi);        /* Ende Kennung dazu                 */
  96.   }
  97.  
  98. /*---------------------------------------------------------------------------*/
  99. VOID    putmsg(string)        /* Meldung an User ausgeben             */
  100. char    *string;
  101.   {
  102.   seteom(putals(string));    /* Meldung mit Endekennung raus             */
  103.   }
  104.  
  105. /*---------------------------------------------------------------------------*/
  106. mhtyp    *putals(string)        /* String nach Nodeident in neuen Buffer     */
  107. char    *string;        /* Rueckgabe: Pointer auf neuen Buffer         */
  108.   {
  109.   register mhtyp *bufpoi;    /* neuer Buffer                     */
  110.  
  111.   bufpoi = (mhtyp *) allocb();        /* neuen Buffer holen             */
  112.   bufpoi->l2lnk = userpo->cblk_u; /* Level2 Kontrollblock in Buffer eintragen*/
  113.   bufpoi->usrtyp = userpo->typ_u; /* Usertyp                     */
  114.  
  115.   putalt(alias, bufpoi);    /* Ident schreiben                 */
  116.   putid(myid, bufpoi);        /* Call schreiben                 */
  117.   putstr("} ", bufpoi);        /* Trennzeichen                     */
  118.   putstr(string, bufpoi);    /* String dazu                     */
  119.   return(bufpoi);
  120.   }
  121.  
  122. /*---------------------------------------------------------------------------*/
  123. VOID    putrou(neigbp, mbhdp)    /* Weg zu einem Nachbarn ausgeben         */
  124. nbrtyp  *neigbp;            /* Pointer auf den Nachbarn         */
  125. mhtyp   *mbhdp;                /* Buffer fuer die Meldung         */
  126.   {
  127.   register nbrtyp  *neigb;        /* Pointer auf den Nachbarn         */
  128.   register mhtyp   *mbhd;        /* Buffer fuer die Meldung         */
  129.  
  130.   neigb = neigbp;
  131.   mbhd = mbhdp;
  132.   putstr((neigb->nbrl2l == NULL)? "\015 " : "\015>", mbhd); /* aktiver Weg?  */
  133.   putnbr(neigb, mbhd);                /* Nachbarn ausgeben         */
  134.   putchr(' ', mbhd);                /* Leerraum             */
  135. #ifdef MODIFIED
  136.   putnum_and_space((neigb->pathqu & 0xff), mbhd); /* Qualitaet des Weges     */
  137. #else
  138.   putnum((neigb->pathqu & 0xff), mbhd);        /* Qualitaet des Weges         */
  139.   putchr(' ', mbhd);                /* Leerraum             */
  140. #endif
  141.   putnum(neigb->nbrrou, mbhd);            /* Zahl der Links         */
  142.   if (neigb->locked == TRUE)            /* Eintrag blockiert?         */
  143.     putstr(" !", mbhd);                /* dann markieren         */
  144.   }
  145.  
  146. /*---------------------------------------------------------------------------*/
  147. VOID    putnbr(neigbp, mbhdp)    /* Daten eines Nachbarn ausgeben         */
  148. nbrtyp  *neigbp;            /* Pointer auf den Nachbarn         */
  149. mhtyp   *mbhdp;                /* Buffer fuer die Meldung         */
  150.   {
  151.   register nbrtyp  *neigb;        /* Pointer auf den Nachbarn         */
  152.   register mhtyp   *mbhd;        /* Buffer fuer die Meldung         */
  153. #ifdef MODIFIED
  154.   register nodtyp  *despoi;        /* pointer for finding alias */
  155. #endif
  156.  
  157.   neigb = neigbp;
  158.   mbhd = mbhdp;
  159.   putchr(' ', mbhd);            /* Trennzeichen                 */
  160. #ifndef MODIFIED
  161.   putnum(neigb->nbrpor, mbhd);        /* Port Nummer                 */
  162.   putchr(' ', mbhd);            /* Trennzeichen                 */
  163. #else
  164.   putnum_and_space(neigb->nbrpor, mbhd);    /* Port Nummer             */
  165.   if( hlpflg & 0x10 )                /* if node alias display on */
  166.     for( despoi = (nodtyp *)destil.lnext;    /* step thru node table until*/
  167.          (nodtyp *)&destil != despoi;        /* match found. */
  168.          despoi = (nodtyp *)despoi->nodlnk.lnext )
  169.       if( cmpid( neigb->nbrcal, despoi->nodcal )) /* If match found, then */
  170.       {
  171.         putalt( despoi->nodide, mbhd );          /* display alias */
  172.         break;
  173.       }
  174. #endif
  175.   putid(neigb->nbrcal, mbhd);        /* Call                     */
  176.   putdil(neigb->nbrdil, mbhd);        /* Digiliste                 */
  177.   }
  178.  
  179. /*---------------------------------------------------------------------------*/
  180. VOID    putuse(seite, linkp, typ, mbhdp) /* User Daten in MBHD legen         */
  181. mhtyp     *mbhdp;            /* Kopf der Messageliste             */
  182. unsigned typ;            /* Usertyp: 0=Host, 2=Level2, 4=Circuit         */
  183. ctyp     *linkp;            /* Kontrollblock                 */
  184. unsigned seite;            /* L=uplink, R=downlink                 */
  185.   {
  186.  
  187.   register ctyp *link;
  188.   register mhtyp *mbhd;
  189.   register unsigned i;
  190.  
  191.   mbhd = mbhdp;
  192.   link = linkp;
  193.  
  194.   switch (typ) {
  195. /*==============================*/
  196.   case 4:            /* User ist Circuit                 */
  197.     putstr("Circuit(", mbhd);
  198.     putalt(link->l3blk.l3node->nodide, mbhd); /* Node ID                 */
  199.     putid_and_space(link->l3blk.downca, mbhd);    /* Node Call                     */
  200.     putid(link->l3blk.upcall, mbhd);    /* User Call                     */
  201.     putchr(')', mbhd);        /* Ende dieser Seite                 */
  202.     break;
  203.  
  204. /*==============================*/
  205.   case 2:            /* User ist Level2                 */
  206.     if (seite == 'L') {        /* Uplink oder Downlink?             */
  207. #ifdef TEXNET
  208.       i = link->l2blk.realid[0] & 0xff;
  209.       i = ( i != 0 && i != 0xff );
  210.       putstr( i ? "TexNet(" : "Uplink(", mbhd);
  211.       putid(link->l2blk.dstid, mbhd);    /* User Call                     */
  212.       if( i )
  213.       {
  214.         putchr( ' ', mbhd );
  215.         putid( link->l2blk.realid, mbhd );
  216.       }
  217. #else
  218.       putstr("Uplink(", mbhd);    /* Uplink:                     */
  219.       putid(link->l2blk.dstid, mbhd);    /* User Call                     */
  220. #endif
  221.       putchr(')', mbhd);
  222.       }
  223.     else {            /* Downlink:                     */
  224.       putstr("Downlink(", mbhd);
  225.       putid_and_space(link->l2blk.srcid, mbhd);    /* User Call                     */
  226.       putid(link->l2blk.dstid, mbhd);    /* Gegenstation                     */
  227.       putchr(')', mbhd);
  228.       }
  229.     break;
  230.  
  231. /*==============================*/
  232.   default:            /* User ist Host                 */
  233.     putstr("Host(", mbhd);
  234.     putalt(alias, mbhd);    /* Host ID                     */
  235.     putid(myid, mbhd);        /* Host Call                     */
  236.     putchr(')', mbhd);
  237.     break;
  238.     }
  239.   }
  240.  
  241. /*---------------------------------------------------------------------------*/
  242. VOID    putdil(liste, mbhd)    /* Digiliste in MBHD legen             */
  243. register mhtyp    *mbhd;        /* Kopf der Messageliste             */
  244. register char    *liste;        /* Digiliste, 0 am Ende                 */
  245. {
  246.   if (*liste != 0) {        /* existiert die Liste?                 */
  247.     putstr(" via", mbhd);
  248.     while (*liste != 0) {    /* so lange der Vorrat reicht             */
  249.       putchr(' ', mbhd);    /* Trennzeichen                     */
  250.       putid(liste, mbhd);    /* Digi ausgeben                 */
  251.       liste += 7;        /* naechster Digi                 */
  252.     }
  253.   }
  254. }
  255.  
  256. /*---------------------------------------------------------------------------*/
  257. VOID    putid(call, mbhd)    /* Call mit SSID in MBHD legen             */
  258. register mhtyp    *mbhd;        /* Kopf der Messageliste             */
  259. char    *call;            /* Call                         */
  260.   {
  261.   register char       zeichen;    /* Scratch bei Ausgabe                 */
  262.   register unsigned cnt;    /* zaehlt Zeichen                 */
  263.   char       ssid;        /* SSID des Calls                 */
  264.  
  265.   for (cnt = 6; cnt != 0; --cnt) { /* 6 Zeichen Call                 */
  266.     zeichen = *call++;        /* naechstes Zeichen holen             */
  267.  
  268.     if (zeichen > ' ')        /* druckbar?                     */
  269.       putchr(zeichen, mbhd);    /* dann raus                     */
  270.  
  271.     else {            /* nicht druckbar:                 */
  272.       if (zeichen < ' ') {    /* Leerzeichen uebergehen             */
  273.         putchr('^', mbhd);    /* Kontrollzeichen mit Prefix             */
  274.         putchr((zeichen + '@'), mbhd);
  275.         }
  276.       }
  277.     }
  278.   ssid = (*call >> 1) & 0x0f;    /* SSID passend schieben             */
  279.   if (ssid != 0) {        /* nur SSID != 0 ausgeben             */
  280.     putchr('-', mbhd);        /* mit Trennstrich                 */
  281.     putnum(ssid, mbhd);
  282.     }
  283.   }
  284.  
  285. /*---------------------------------------------------------------------------*/
  286. VOID    putnod(mbhd)        /* Knoten Info in MBHD legen             */
  287. register mhtyp    *mbhd;        /* Kopf der Messageliste             */
  288. {
  289.   putalt(despoi->nodide, mbhd);    /* Ident ausgeben                 */
  290.   putid(despoi->nodcal, mbhd);    /* und Call                     */
  291. }
  292.  
  293. /*---------------------------------------------------------------------------*/
  294. VOID    putalt(ident, mbhd)    /* Ident in Buffer MBHD legen             */
  295. register mhtyp    *mbhd;        /* Kopf der Messageliste             */
  296. register char    *ident;        /* auszugebender Ident                 */
  297. {
  298.   if (*ident != ' ') {        /* ueberhaupt definiert?             */
  299.     putcal(ident, mbhd);    /* dann ausgeben                 */
  300.     putchr(':', mbhd);        /* Trennzeichen hinterher             */
  301.   }
  302. }
  303.  
  304. /*---------------------------------------------------------------------------*/
  305. VOID    putcal(call, mbhd)    /* Call in Buffer MBHD legen             */
  306. mhtyp    *mbhd;            /* Kopf der Messageliste             */
  307. char    call[];            /* auszugebendes Call                 */
  308.   {
  309.   register char       zeichen;    /* Scratch fuer aktuelles Zeichen         */
  310.   register unsigned cnt;    /* Zaehler fuer Zeichen im Call             */
  311.  
  312.   for (cnt = 0; cnt < 6; ++cnt) { /* Call ist immer 6 Zeichen lang         */
  313.     zeichen = call[cnt];
  314.     if (zeichen == ' ')        /* Leerzeichen nicht ausgeben             */
  315.       break;
  316.     putchr(zeichen, mbhd);
  317.     }
  318.   }
  319.  
  320. /*---------------------------------------------------------------------------*/
  321. VOID    putnum(zahl, mbhd)    /* Zahl in Buffer MBHD legen             */
  322. mhtyp     *mbhd;            /* Kopf der Messageliste             */
  323. unsigned zahl;            /* auszugebende Zahl                 */
  324.   {
  325.   unsigned notnul;        /* fuehrende Null j/n                 */
  326.   register unsigned diviso;    /* Stellenwert der aktuellen Stelle         */
  327.   register unsigned ziffer;    /* aktuelle Ziffer                 */
  328.   register unsigned numcnt;    /* Zahl der ausgegebenen Ziffern         */
  329.  
  330.   notnul = 0;
  331.   diviso = 10000;
  332.   for(numcnt = 5; numcnt != 0; --numcnt) {
  333.     ziffer = zahl / diviso;
  334.     if ((ziffer != 0) || (notnul /*== 1*/) || (diviso == 1)) {
  335.       putchr((ziffer + '0'), mbhd); /* Stelle ausgeben                 */
  336.       notnul = 1;
  337.       }
  338.     zahl %= diviso;
  339.     diviso /= 10;
  340.     }
  341.   }
  342.  
  343. /*---------------------------------------------------------------------------*/
  344. VOID    putstr(string, mbhd)    /* String in Buffer MBHD legen             */
  345. register char    *string;    /* auszugebender String                 */
  346. register mhtyp    *mbhd;        /* Kopf der Messageliste             */
  347.   {
  348.   while (*string != 0) {    /* so lange der Vorrat reicht             */
  349.     putchr(*string++, mbhd);    /* weg damit                     */
  350.     }
  351.   }
  352.  
  353. /*---------------------------------------------------------------------------*/
  354. VOID    putspa(stop, mbhd)    /* bis stop die Zeile mit Space fuellen         */
  355. unsigned stop;                /* Ende der Leerraeume             */
  356. register mhtyp    *mbhd;        /* Buffer der Meldung             */
  357.   {
  358.   register unsigned cnt;        /* Scratch Zaehler             */
  359.  
  360.   cnt = mbhd->l4time + stop - mbhd->putcnt;
  361.   if( cnt > 128 ) 
  362.     return;
  363.   while (cnt--)
  364.    {
  365.     putchr(' ', mbhd);
  366.    }
  367.   }
  368.  
  369. /*---------------------------------------------------------------------------*/
  370. unsigned skipspace()
  371. {
  372.     return( skipsp( &clicnt, &clipoi ) );
  373. }
  374.  
  375. /*---------------------------------------------------------------------------*/
  376. unsigned nextnumber()
  377. {
  378.     return( nxtnum(&clicnt, &clipoi) );
  379. }
  380.  
  381. /*---------------------------------------------------------------------------*/
  382. BOOLEAN getqua()
  383.   {
  384.    return (
  385.               (skipspace() )
  386.            && ((nquali = nextnumber() ) <= 255)
  387.           );
  388.   }
  389.  
  390.  
  391. /*---------------------------------------------------------------------------*/
  392. BOOLEAN getpar()        /* Parameter fuer Ziel holen             */
  393.   {
  394.    return (
  395.              (skipspace() )
  396.            && ((nport = nextnumber() ) < NUMPORTS)
  397.            && (getcal(&clicnt, &clipoi, VCpar, ncall) == TRUE)
  398.            && (getdig(&clicnt, &clipoi, FALSE, ndigi) != ERROR)
  399.            );
  400.   }
  401.  
  402. /*---------------------------------------------------------------------------*/
  403. getdig(laenge, inbuf, pflag, outbuf)          /* Digiliste aus Buffer holen  */
  404. unsigned *laenge;        /* Laenge des Eingabebuffers             */
  405. char     *(*inbuf);        /* Eingabebuffer                 */
  406. char     pflag;            /* Call-pruefen Flag                 */
  407. char     *outbuf;        /* Ziel fuer das Call                 */
  408.   {
  409.   char       liste[8*7 +1];    /* Zwischenspeicher                 */
  410.   char       *ibufer;        /* Kopie von inbuf                 */
  411.   unsigned ilaeng;        /* Kopie von laenge                 */
  412.   register unsigned zeichen;    /* Scratch                     */
  413.   register char       *lispoi;    /* Pointer in liste                 */
  414.   register unsigned cnt;    /* Zaehler, Scratch                 */
  415.   unsigned caltyp;        /* Typ des letzten Call: 0=leer, -1=niO, 1=OK*/
  416.  
  417.   ibufer = *inbuf;        /* eine Indirektion weniger             */
  418.   ilaeng = *laenge;
  419.   if (getcal(&ilaeng, &ibufer, 0, liste) == 1) { /* Call da?             */
  420.     lispoi = liste;        /* koennte "VIA" vorher sein             */
  421.     if (*lispoi++ == 'V') {    /* stimmt erstes Zeichen?             */
  422.       for (cnt = 0; cnt < 5; ++cnt) { /* ja: max 5 Zeichen testen         */
  423.         zeichen = *lispoi++;    /* naechstes Zeichen                 */
  424.         if (zeichen != ' ') {    /* Ende von "VIA"?                 */
  425.           if (!((cnt == 0) && (zeichen == 'I') ||
  426.               (cnt == 1) && (zeichen == 'A')))
  427.             break;        /* Rechtschreibung muss stimmen             */
  428.           }
  429.         }
  430.       if (cnt == 5) {        /* VIA + ' ' = 4                 */
  431.         *inbuf = ibufer;    /* wenn nicht VIA gefunden, korrigieren         */
  432.         *laenge = ilaeng;
  433.         }
  434.       }
  435.     }
  436.  
  437.   for (cnt = 8, lispoi = liste; cnt != 0; --cnt, lispoi +=7)
  438.    {                        /* maximal 8 Digis         */
  439.     if (*laenge != 0)
  440.      {
  441.       if (((zeichen = *(*inbuf)) == '+')
  442.          ||(zeichen == '-'))
  443.         break;
  444.      }
  445.     if ((caltyp = getcal(laenge, inbuf, pflag, lispoi)) == -1) /* ungueltig? */
  446.       return(-1);                /* Abbruch             */
  447.     if (caltyp == 0) break;            /* nichts mehr da: Ende         */
  448.    }
  449.  
  450.   *lispoi = 0;                    /* Endekennung             */
  451.   cpyidl(outbuf, liste);            /* in Ziel kopieren         */
  452.   return(*outbuf != 0);                /* Erfolg melden         */
  453.   }
  454.  
  455. /*---------------------------------------------------------------------------*/
  456. getcal(laenge, inbuf, pflag, outbuf) /* Call aus Buffer holen             */
  457. unsigned *laenge;        /* Laenge des Eingabebuffers             */
  458. char     *(*inbuf);        /* Eingabebuffer                 */
  459. char     pflag;            /* Call-pruefen Flag                 */
  460. char     *outbuf;        /* Ziel fuer das Call                 */
  461.   {
  462.   char       call[7];        /* Zwischenspeicher                 */
  463.   register char       binsid;    /* SSID, binaer                     */
  464.   register char       *bufpoi;    /* Pointer in Call                 */
  465.   register char       zeichen;    /* Scratch                     */
  466.   unsigned cnt;            /* Zaehler, Scratch                 */
  467.  
  468.   bufpoi = call;        /* auf Anfang                     */
  469. #ifdef MODIFIED
  470.   cpy6ch( bufpoi, nulide );
  471.   bufpoi[6] = 0x60;
  472. #else
  473.   for (cnt = 0; cnt < 6; ++cnt)    /* Zwischenspeicher loeschen             */
  474.     *bufpoi++ = ' ';
  475.   *bufpoi = 0x60;        /* kein SSID                     */
  476. #endif
  477.  
  478.   skipsp(laenge, inbuf);    /* auf erstes Zeichen != ' '             */
  479.  
  480.   bufpoi = call;        /* wieder nach vorn                 */
  481.   cnt = 0;            /* gelesene Zeichen = 0                 */
  482.   while (*laenge != 0) {    /* so lange Zeichen da sind             */
  483.     if (((zeichen = upcase(*(*inbuf)))/* und gueltig                 */
  484.        == ' ' ) || (zeichen == ',')) break;
  485.     if (zeichen < ' ') return(ERROR);
  486.     if (zeichen == '-') {    /* Trennung zum SSID?                 */
  487.       if ((cnt == 0) || (*laenge == 0))
  488.         return(ERROR);        /* Fehler: kein Call oder SSID             */
  489.       ++(*inbuf);        /* Trennung uebergehen                 */
  490.       --(*laenge);
  491.       if (*laenge == 0) return (ERROR); /* SSID angesagt, kommt aber nicht   */
  492.       zeichen = *(*(inbuf));    /* erste Ziffer SSID holen             */
  493.       if ((zeichen < '0') || (zeichen > '9'))
  494.         return(ERROR);        /* ungueltige Ziffer                 */
  495.       ++(*inbuf);
  496.       --(*laenge);        /* Ziffer ist verbraucht             */
  497.       binsid = (zeichen + 0xffd0); /* Binaer merken                 */
  498.       if (*laenge != 0) {    /* noch Zeichen da?                 */
  499.         zeichen = *(*inbuf);    /* holen                     */
  500.         if ((zeichen >= '0') && (zeichen <= '9')) { /* gueltige Ziffer?         */
  501.           binsid *= 10;        /* erste Ziffer eine Stelle nach links         */
  502.           binsid += (zeichen + 0xffd0) ; /* + neue Ziffer             */
  503.           if (binsid > 15)
  504.             return(ERROR);        /* ungueltiger SSID             */
  505.           ++(*inbuf);        /* letzte Ziffer verbrauchen             */
  506.           --(*laenge);
  507.           }
  508.         }
  509.       call[6] = (binsid << 1) | 0x60; /* SSID merken                 */
  510.       break;
  511.       }
  512.     else {            /* kein SSID, anderes Zeichen             */
  513.       if (cnt++ == 6)
  514.         return(ERROR);        /* Call zu lang                     */
  515.       *bufpoi++ = zeichen;    /* Zeichen merken                 */
  516.       ++(*inbuf);        /* Lesepointer rauf                 */
  517.       --(*laenge);
  518.       }
  519.     }
  520.                 /* Call ist im Buffer                 */
  521.   while (*laenge != 0) {    /* Rest des Buffers ansehen             */
  522.     zeichen = *(*inbuf);    /* Zeichen holen                 */
  523.     if ((zeichen != ' ') && (zeichen != ','))
  524.       break;            /* kein Trennzeichen, stop             */
  525.     ++(*inbuf);            /* naechstes Zeichen                 */
  526.     --(*laenge);
  527.     if (zeichen == ',') break;    /* Leerraum uebergehen                 */
  528.     }
  529.   if (cnt == 0) return(0);    /* Call war leer                 */
  530.   if (fvalca(pflag, call) == ERROR)
  531.     return(ERROR);            /* Call war ungueltig             */
  532.   cpyid(outbuf, call);        /* Call kopieren                 */
  533.   return(1);            /* ok melden                     */
  534.   }
  535.  
  536. /*---------------------------------------------------------------------------*/
  537. unsigned getide(buffer)        /* Ident aus cli-Buffer holen             */
  538. char    buffer[];        /* -1=kein Erfolg, 0=leer, 1=Erfolg         */
  539.   {
  540.   char       ident[6];        /* Zwischenspeicher                 */
  541.   register char       zeichen;    /* Scratch                     */
  542.   register unsigned cnt;    /* Zaehler, Scratch                 */
  543.  
  544.   cpy6ch(ident, nulide);            /* Zwichenspeicher loeschen  */
  545.  
  546.   for (cnt = 0; (cnt < 6) && (clicnt != 0); ++cnt)
  547.     {
  548.       zeichen = *clipoi;/* Zeichen aus CLI-Buffer holen         */
  549.       nxtcli();
  550. #ifdef MODIFIED
  551.       if( !(hlpflg & 0x40 ))
  552. #endif
  553.         zeichen = upcase( zeichen );
  554.       if (zeichen != ' ')        /* Schluss bei Trennzeichen         */
  555.         {
  556.           if (((zeichen >= 'A') && (zeichen <= 'Z'))
  557.              || ((zeichen >= '0') && (zeichen <= '9'))
  558. #ifdef MODIFIED
  559.              || ((zeichen >= 'a') && (zeichen <= 'z'))
  560. #endif
  561.              || ((cnt == 0) && (zeichen == '#'))) /* gueltiges Zeichen?         */
  562.             {
  563.               ident[cnt] = zeichen;
  564.               continue;
  565.             }
  566.           if ((cnt != 0) || (zeichen != '*')) return(-1); /* '*' als Ident   */
  567.         }
  568.       break;
  569.     }
  570.  
  571.   if ((cnt == 6) && (clicnt != 0) && (*clipoi) != ' ')
  572.     return(-1);            /* Ident zu lang? Fehler melden             */
  573.  
  574.   if (valcal(ident) == 1)
  575.     return(-1);            /* Ident darf kein Call sein             */
  576.  
  577.   cpy6ch(buffer, ident);            /* umkopieren             */
  578.  
  579.   return(ident[0] != ' ');
  580.   }
  581.  
  582. /*---------------------------------------------------------------------------*/
  583. unsigned nxtnum(laenge, buffer)    /* Zahl aus Buffer holen             */
  584. register char     *(*buffer);    /* Buffer                     */
  585. register unsigned *laenge;    /* Laenge des Buffers                 */
  586.   {
  587.   register unsigned temp;    /* Scratch                     */
  588.  
  589.   skipsp(laenge, buffer);    /* auf erstes Zeichen != ' '             */
  590.   temp = 0;            /* Ergebniss = 0                 */
  591.   while ((*laenge != 0) && (*(*buffer) >= '0') && (*(*buffer) <='9')) {
  592.     --*laenge;            /* mitzaehlen                     */
  593.     temp *= 10;            /* Ergebniss eine Stelle weiter             */
  594.     temp += (*(*buffer)++ + 0xffd0);/* + naechstes Digit             */
  595.     }
  596.   return (temp);        /* mit Ergebniss zurueck             */
  597.   }
  598.  
  599. /*---------------------------------------------------------------------------*/
  600. fvalca(pflag, call)        /* Call pruefen: 0=leeres call, ohne Flag    */
  601. register char    *call;            /* -1=niO (m. Flag), 1=ok oder o. Flag         */
  602. BOOLEAN pflag;
  603.   {
  604.   if (*call == ' ' ) return(0);    /* leer                         */
  605.   if (!pflag) return (1);    /* nicht pruefen                 */
  606.   return (valcal(call));    /* pruefen, valcal liefert Ergebniss         */
  607.   }
  608.  
  609. /*---------------------------------------------------------------------------*/
  610. valcal(call)            /* Call auf Gueltigkeit pruefen             */
  611. char    *call;            /* -1=ungueltiges Zeichen, 1=Call ist ok     */
  612.   {
  613.   char       *numpos;        /* Position der Zahl im Call             */
  614.   register char       *actual;    /* Pointer auf aktuelles Zeichen         */
  615.   register char       zeichen;    /* aktuelles Zeichen                 */
  616.   register unsigned cnt;    /* gepruefte Zeichen                 */
  617.   unsigned zahl;        /* Zahlen im Call                 */
  618.  
  619.   for (
  620.     zahl = 0,            /* keine Zahl gefunden                 */
  621.     cnt = 6,            /* nichts geprueft                 */
  622.     actual = call;        /* auf Anfang                     */
  623.     cnt != 0;            /* maximal 6 Zeichen Call             */
  624.     --cnt, ++actual) {
  625.     if ((zeichen = *actual) == ' ') /* Ende des Calls?                 */
  626.       break;
  627.     if (!((zeichen >= 'A') && (zeichen <= 'Z'))){ /* Alfa ist immer gut         */
  628.       if ((zeichen >= '0') && (zeichen <= '9')) {
  629.         zahl += 1;        /* Zahlen zaehlen                 */
  630.         numpos = actual;    /* Position merken                 */
  631.       }
  632.       else return(-1);        /* ungueltiges Zeichen im Call             */
  633.       }
  634.     }
  635.   if (
  636.        ((actual - call) < 4)    /* minimal 4 Zeichen                 */
  637.     || (zahl == 0)        /* mindestens 1 Zahl                 */
  638.     || (zahl > 2)        /* maximal 2 Zahlen                 */
  639.     || (numpos == call)        /* keine Zahl an erster Stelle             */
  640.     || (numpos == (actual -1)))    /* mindestens 2 Buchstaben Suffix         */
  641.     return(-1);            /* Call ist ungueltig                 */
  642.   else return(1);        /* Call ist gueltig                 */
  643.   }
  644.  
  645. /*---------------------------------------------------------------------------*/
  646. BOOLEAN ismemr()        /* Test auf genuegend freien Speicher         */
  647.   {
  648.   if((nmbfre < 256) && (!userpo->sysflg))    /* Platz oder Sysop?         */
  649.    {
  650.     putmsg("Node busy");
  651.     return(FALSE);
  652.    }
  653. #ifdef MODIFIED
  654.   cpyid(usrcal, this_station() );
  655. #else
  656.   cpyid(usrcal, calofs('U', userpo->cblk_u, userpo->typ_u));
  657. #endif
  658.   return(TRUE);
  659.   }
  660.  
  661. /*---------------------------------------------------------------------------*/
  662. VOID setl2b()            /* User Kontrollblock aufbauen             */
  663.   {
  664.   userpo->cblk_p = lnkpoi;            /* Pointer auf L2-Block         */
  665.   userpo->typ_p = 2;                /* Partner ist L2         */
  666.   userpo->status = 2;                /* Status: connect laeuft    */
  667.   cpyid(lnkpoi->srcid, usrcal);            /* Call eintragen         */
  668.   }
  669.  
  670. /*---------------------------------------------------------------------------*/
  671. char *calofs(seite, link, user)    /* Offset Call-String im Kontrollblock         */
  672. unsigned user;            /* Usertyp: 0=Host, 2=L2-User, 4=Circuit     */
  673. register ctyp     *link;            /* Linkkontrollblock                 */
  674. unsigned seite;            /* Seite der Verbindung: U=uplink, D=downlink*/
  675.   {
  676.   register unsigned char i;
  677.  
  678.   if (user == 4) {        /* Circuit?                     */
  679.     return ((seite == 'D') ?    /* welche Seite?                 */
  680.       link->l3blk.downca : link->l3blk.upcall);
  681.     }
  682.   if (user == 2)        /* L2-User?                     */
  683.   {
  684. #ifdef TEXNET
  685.     if( seite != 'D' )
  686.       return( ( i = link->l2blk.realid[0] ) != 0 && i != 0xff ?
  687.               link->l2blk.realid : link->l2blk.dstid );
  688.     else
  689. #endif
  690.     return(link->l2blk.dstid);
  691.   }
  692.   else return(myid);        /* muss Host sein                 */
  693.   }
  694.  
  695. /*---------------------------------------------------------------------------*/
  696. BOOLEAN getlin(mbhdp)        /* Zeile im Messagebuffer verfuegbar?         */
  697. mhtyp    *mbhdp;
  698.   {
  699. register char     *nextch;    /* naechstes Zeichen                 */
  700. register unsigned getcou;    /* verfuegbare Zeichen                 */
  701. BOOLEAN  found;            /* Flag: Ueberlauf                 */
  702. unsigned laenge;        /* Laenge der Zeile                 */
  703. register mhtyp    *mbhd;
  704.   
  705.   mbhd = mbhdp;
  706.  
  707.   nextch = mbhd->nxtchr;    /* Pointer auf naechstes Zeichen         */
  708.   getcou = mbhd->getcnt;    /* verfuegbare Zeichen                 */
  709.   found = FALSE;        /* default: Zeile nicht da             */
  710.   laenge = 0;            /* Laenge initialisieren             */
  711.   while (mbhd->getcnt < mbhd->putcnt) { /* so lange Vorrat reicht         */
  712.     if (((getchr(mbhd) & 0x7f) == 0x0d) /* Zeichen = Zeilenende?         */
  713.       || (++laenge == 81)){    /* Zeile zu lang?                 */
  714.       found = TRUE;        /* markieren                     */
  715.       break;
  716.      }
  717.     }
  718.   mbhd->nxtchr = nextch;    /* MBHD auf alte Werte zurueck             */
  719.   mbhd->getcnt = getcou;
  720.   return (found);
  721.   }
  722.  
  723. /*---------------------------------------------------------------------------*/
  724. invsid()            /* SSID umdrehen                 */
  725.   {
  726.   usrcal[6] = 0x7e - (usrcal[6] & 0x1e);
  727.   }
  728.  
  729. /*---------------------------------------------------------------------------*/
  730. BOOLEAN issyso()        /* Test auf Sysop Attribut             */
  731.   {
  732.   return (
  733.              (userpo->sysflg == TRUE )
  734.           && (skipspace() ) /* kein Sysop ohne Eingabe   */
  735.          );
  736.   }
  737.  
  738. /*---------------------------------------------------------------------------*/
  739. unsigned skipsp(laenge, string)    /* in String auf naechstes Zeichen != ' '    */
  740. register unsigned *laenge;    /* Laenge des String, wird korrigiert         */
  741. register char     *(*string);    /* die Adresse des Kandidaten             */
  742.   {
  743.   while ((*laenge != 0) && (*(*string) == ' ')) {
  744.     ++*string;
  745.     --*laenge;
  746.     }
  747.   return (*laenge != 0);
  748.   }
  749.  
  750. /*---------------------------------------------------------------------------*/
  751. #ifndef BANKED
  752. VOID timer()            /* alle 10ms Uhrzeit erhoehen             */
  753.   {
  754.   ++tic10;
  755.   }
  756. #endif
  757.  
  758. /*---------------------------------------------------------------------------*/
  759. unsigned skipnext(laenge, string)    /* skip over != ' ' & to char != ' ' */
  760. register unsigned *laenge;        /* Laenge des String, wird korrigiert*/
  761. register char     *(*string);        /* die Adresse des Kandidaten         */
  762.   {
  763.   while ((*laenge != 0) && (*(*string) != ' ')) {
  764.     ++*string;
  765.     --*laenge;
  766.     }
  767.   return ( skipsp( laenge, string ) );
  768.   }
  769.  
  770. /*---------------------------------------------------------------------------*/
  771. /* small utility to save some space - bump line pointer counters
  772.  */
  773. #ifdef PORTABLE
  774. VOID nxtcli()
  775. {
  776.     clicnt--;
  777.     clipoi++;
  778. }
  779.  
  780. #else
  781. #asm
  782.     public nxtcli_
  783. nxtcli_: lhld clipoi_        ; clipoi++
  784.     inx h
  785.     shld clipoi_
  786.     lhld clicnt_        ; clicnt--
  787.     dcx h
  788.     shld clicnt_
  789.     ret
  790. #endasm
  791. #endif
  792.  
  793.  
  794. /*---------------------------------------------------------------------------*/
  795.  
  796. VOID putid_and_space( ident, bufpoi )
  797. register mhtyp *bufpoi;
  798. char *ident;
  799. {
  800.             putid( ident, bufpoi );
  801.             putchr( ' ', bufpoi );
  802. }
  803.  
  804. /* -----------------------------------------------------------------------
  805.  * Block_code is used tro replace the '-' characters in <--> if one
  806.  * or other patchcord entry is choked.
  807.  */
  808.  
  809. #ifdef CHOKE_FLAGS
  810.  
  811. block_code( link, type, mbhd )
  812. ctyp *link;
  813. unsigned type;
  814. mhtyp *mbhd;
  815. {
  816.     register unsigned i = '-';
  817.     
  818.     switch( type )
  819.     {
  820.         case 2:
  821.             if( link->l2blk.flag & L2FBUSY )
  822.                 i = 'C';
  823.             break;
  824.         case 4:
  825.             switch( link->l3blk.l4flag & 0x60 )
  826.             {
  827.                 case 0x40:
  828.                     i = 'L';
  829.                     break;
  830.                 case 0x20:
  831.                     i = 'R';
  832.                     break;
  833.                 case 0x60:
  834.                     i = 'C';
  835.             }
  836.     }
  837.     putchr( i, mbhd );
  838. }
  839.  
  840. #endif
  841.